package cn.sykj.car.service.impl;

import cn.sykj.car.common.StatusCode;
import cn.sykj.car.dict.DeleteFlagEnum;
import cn.sykj.car.entity.Menu;
import cn.sykj.car.entity.MenuOperationConfig;
import cn.sykj.car.exception.CommonException;
import cn.sykj.car.exception.ParameterInvalidException;
import cn.sykj.car.mapper.MenuMapper;
import cn.sykj.car.service.IMenuOperationConfigService;
import cn.sykj.car.service.IMenuService;
import cn.sykj.car.service.IOperationService;
import cn.sykj.car.utils.Utils;
import cn.sykj.car.vo.RolesVO;
import cn.sykj.car.vo.SysMenuVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 菜单 服务实现类
 * </p>
 *
 * @author Yixu
 * @since 2018-11-29
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Resource
    IMenuOperationConfigService iMenuOperationConfigService;

    @Resource
    IOperationService iOperationService;

    /**
     * 添加菜单
     *
     * @param menu
     * @return
     * @throws Exception
     * @author yuhao
     * @version 2018-12-04 15:59
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public boolean insertMenu(SysMenuVO menu) throws Exception {

        if (Utils.isEmpty(menu)) {
            throw new ParameterInvalidException();
        }

        if(Utils.isEmpty(menu.getPid())){
            menu.setPid(0);
        }
        // 先保存菜单
        boolean ret = this.save(menu);

        // 保存菜单对应权限
        if(Utils.notEmpty(menu.getMenuOperationConfigList())&&menu.getMenuOperationConfigList().size()>0){
            List<MenuOperationConfig> menuOperationConfigs = menu.getMenuOperationConfigList();
            for(MenuOperationConfig moc : menuOperationConfigs){
                moc.setDelFlag(DeleteFlagEnum.FALSE.VALUE);
                moc.setMenuId(menu.getId());
            }

            // 批量保存菜单-操作按钮权限
            ret &= iMenuOperationConfigService.saveBatch(menuOperationConfigs);
        }


        return ret;
    }

    /**
     * 修改菜单
     *
     * @param menu
     * @return
     * @throws Exception
     * @author yuhao
     * @version 2018-12-04 17:18
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public boolean updateMenu(SysMenuVO menu) throws Exception {
        if (Utils.isEmpty(menu) || Utils.isEmpty(menu.getId())) {
            throw new ParameterInvalidException();
        }

        Menu oMenu = this.getById(menu.getId());
        if (Utils.isEmpty(oMenu)) {
            throw new CommonException(StatusCode.MENU_NOT_FOUND.getCode(),StatusCode.MENU_NOT_FOUND.getMsg());
        }

        // 先修改
        boolean ret = this.updateById(menu);

        // 查询该菜单原有权限
        QueryWrapper<MenuOperationConfig> mocCondition = new QueryWrapper<>();
        mocCondition.eq(MenuOperationConfig.MENU_ID,menu.getId());
        List<MenuOperationConfig> o_list = iMenuOperationConfigService.list(mocCondition);
        if(o_list.size()>0){
            for(MenuOperationConfig moc : o_list){
                ret &= iMenuOperationConfigService.removeById(moc.getId());
            }
        }

        // 批量新增权限
        if(Utils.notEmpty(menu.getMenuOperationConfigList())&&menu.getMenuOperationConfigList().size()>0){
            List<MenuOperationConfig> menuOperationConfigs = menu.getMenuOperationConfigList();
            for(MenuOperationConfig moc : menuOperationConfigs){
                moc.setDelFlag(DeleteFlagEnum.FALSE.VALUE);
                moc.setMenuId(menu.getId());
            }

            // 批量保存菜单-操作按钮权限
            ret &= iMenuOperationConfigService.saveBatch(menuOperationConfigs);
        }


        return ret;
    }

    /**
     * 删除菜单
     *
     * @param menu 根据id删除菜单
     * @return
     * @throws Exception
     * @author yuhao
     * @version 2018-12-05 10:15
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public boolean deleteMenu(Menu menu) throws Exception {

        // 参数不存在
        if(Utils.isEmpty(menu)||Utils.isEmpty(menu.getId())){
            throw new ParameterInvalidException();
        }

        // 判断当前菜单是否已不存在
        Menu oMenu = this.getById(menu.getId());
        if(Utils.isEmpty(oMenu)){
            throw new CommonException(StatusCode.MENU_NOT_FOUND.getCode(),StatusCode.MENU_NOT_FOUND.getMsg());
        }

        // 判断对当前菜单是否父级菜单，且父级菜单下是否有子级菜单
        QueryWrapper<Menu> queryConditions = new QueryWrapper<>();
        queryConditions.eq(Menu.PID, menu.getId());
        List<Menu> subMenu = this.list(queryConditions);
        if(oMenu.getPid()==0&&subMenu.size()>0){
            throw new CommonException(StatusCode.MENU_EXIST_SUB.getCode(),StatusCode.MENU_EXIST_SUB.getMsg());
        }

        // 删除
        if(this.removeById(menu.getId())){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 查看单个菜单
     *
     * @param menu
     * @return
     * @author yuhao
     * @version 2018-12-05 10:53
     */
    @Override
    public SysMenuVO selectOneMenu(Menu menu) {

        Menu o_menu = this.getById(menu.getId());
        SysMenuVO sysMenuVO = new SysMenuVO();
        if(Utils.notEmpty(o_menu)){
            BeanUtils.copyProperties(o_menu,sysMenuVO);
        }

        // 根据menuId获取全部权限
        QueryWrapper<MenuOperationConfig> mocCondition = new QueryWrapper<>();
        mocCondition.eq(MenuOperationConfig.MENU_ID,menu.getId());
        mocCondition.orderByAsc(MenuOperationConfig.ID);
        List<MenuOperationConfig> mocList = iMenuOperationConfigService.list(mocCondition);
        if(mocList.size()>0){
            sysMenuVO.setMenuOperationConfigList(mocList);
        }

        return sysMenuVO;
    }

    /**
     * 查看菜单集合
     * @return
     * @author yuhao
     * @version 2018-12-05 10:53
     */
    @Override
    public List<SysMenuVO> selectAllMenu() {

        List<SysMenuVO> firstMenuList = baseMapper.selectMenuAll();
        for(int i=0;i<firstMenuList.size();i++){
            SysMenuVO firstMenuVO = firstMenuList.get(i);
            List<SysMenuVO> secondList = firstMenuVO.getChildren();
            for(int j=0;j<secondList.size();j++){
                SysMenuVO secondMenuVO = secondList.get(j);
                List<SysMenuVO> thirdList = secondMenuVO.getChildren();
                for(int k=0;k<thirdList.size();k++){
                    SysMenuVO thirdMenuVO = thirdList.get(k);

                    QueryWrapper<MenuOperationConfig> mocCondition = new QueryWrapper<>();
                    mocCondition.eq(MenuOperationConfig.MENU_ID,thirdMenuVO.getId());
                    mocCondition.orderByAsc(MenuOperationConfig.ID);
                    List<MenuOperationConfig> mocList = iMenuOperationConfigService.list(mocCondition);
                    if(mocList.size()>0){
                        thirdMenuVO.setMenuOperationConfigList(mocList);
                    }
                }
            }
        }
        return firstMenuList;
    }

    /**
     * 根据角色id查询菜单
     *
     * @param sysRoles
     * @return
     * @author yuhao 2018-12-07 15:56
     */
    @Override
    public List<SysMenuVO> selectMenusByRoleId(RolesVO sysRoles){

        if (Utils.isEmpty(sysRoles)){
            throw new ParameterInvalidException();
        }

        List<Integer> roleIds = new ArrayList<>();

        roleIds.add(sysRoles.getId());

        SysMenuVO sysMenuVO = new SysMenuVO();
        sysMenuVO.setRoleIds(roleIds);

        List<SysMenuVO> list = baseMapper.selectMenusByRoleIds(sysMenuVO);
        for(int i=0;i<list.size();i++){
            SysMenuVO firstMenuVO = list.get(i);
            List<SysMenuVO> secondList = firstMenuVO.getChildren();
            for(int j=0;j<secondList.size();j++){
                SysMenuVO secondMenuVO = secondList.get(j);
                List<SysMenuVO> thirdList = secondMenuVO.getChildren();
                for(int k=0;k<thirdList.size();k++){
                    SysMenuVO thirdMenuVO = thirdList.get(k);

                    // 根据菜单id，查询菜单对应的权限
                    List<MenuOperationConfig> retList = new ArrayList<>();

                    if(Utils.notEmpty(thirdMenuVO.getPermissionCode())){
                        String[] opArr = thirdMenuVO.getPermissionCode().split(":");
                        String[] opVal = opArr[1].split(",");
                        for(int m=0;m<opVal.length;m++){
                            String oValue = opVal[m];
                            MenuOperationConfig menuOperationConfig = new MenuOperationConfig();
                            menuOperationConfig.setOperationValue(oValue);
                            retList.add(menuOperationConfig);
                        }
                    }

                    thirdMenuVO.setMenuOperationConfigList(retList);
                }
            }
        }
        return list;
    }

    @Override
    public List<Menu> selectMenusByRoleIds(List<Integer> roleIds) {

        if (Utils.isEmpty(roleIds)){
            throw new ParameterInvalidException();
        }


        // 先查一级菜单
        List<Menu> menus = baseMapper.selectMenusByRoleIdsAndPid(0, roleIds);

        return menus;
    }

    /**
     * 查看二级和三级菜单，根据用户角色返回的二级、三级菜单
     *
     * @param sysMenuVO
     * @return
     */
    @Override
    public List<SysMenuVO> selectSecondMenuAndThirdMenu(SysMenuVO sysMenuVO) {

        if (Utils.isEmpty(sysMenuVO)|| Utils.isEmpty(sysMenuVO.getId())){
            throw new ParameterInvalidException();
        }

        List<SysMenuVO> secondList = baseMapper.selectSecondMenuAndThirdMenu(sysMenuVO);
        for(int i=0;i<secondList.size();i++){
            SysMenuVO secondMenuVO = secondList.get(i);
            List<SysMenuVO> thirdList = secondMenuVO.getChildren();
            for(int k=0;k<thirdList.size();k++){
                SysMenuVO thirdMenuVO = thirdList.get(k);

                // 根据菜单id，查询菜单对应的权限
                List<MenuOperationConfig> retList = new ArrayList<>();

                if(Utils.notEmpty(thirdMenuVO.getPermissionCode())){
                    String[] opArr = thirdMenuVO.getPermissionCode().split(":");
                    String[] opVal = opArr[1].split(",");
                    for(int m=0;m<opVal.length;m++){
                        String oValue = opVal[m];
                        MenuOperationConfig menuOperationConfig = new MenuOperationConfig();
                        menuOperationConfig.setOperationValue(oValue);
                        retList.add(menuOperationConfig);
                    }
                }

                thirdMenuVO.setMenuOperationConfigList(retList);
            }
        }

        return secondList;
    }

    @Override
    public List<SysMenuVO> selectFirstMenusByRoleIds(SysMenuVO condition) {

        if(Utils.isEmpty(condition)||condition.getRoleIds().size()==0){
            throw new CommonException(StatusCode.UN_AUTHORIZED.getCode(),StatusCode.UN_AUTHORIZED.getMsg());
        }

        List<SysMenuVO> list = baseMapper.selectFirstMenusByRoleIds(condition);
        return list;
    }

}
